#!/usr/bin/env python

""" Debrew web interface. This was based on the blog example from web.py """
import web
#from web import web, template
from background import background, backgrounder
import Runner
import model
import json
from Block import Block
import Gcode

import time
import os, os.path
import sys

from multiprocessing import Process, Value, Array


import logging
import logging.handlers

my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

handler = logging.handlers.SysLogHandler(address = '/dev/log')

my_logger.addHandler(handler)

### Url mappings

urls = (
    '/', 'Index',
    '/view/(\d+)', 'View',
    '/new', 'New',
    '/delete/(\d+)', 'Delete',
    '/edit/(\d+)', 'Edit',
    '/run', 'Run',
    '/line', 'Line', 
    '/ajax', 'Ajax',
    '/ajax/get_gcodes/(\d+)', 'Ajax'
)


### Templates
t_globals = {
    'datestr': str
}
render = web.template.render('templates', base='base', globals=t_globals)


class Index:

    def GET(self):
        """ Show page """
        profiles = model.get_profiles()
        return render.index(profiles)


class View:

    def GET(self, id):
        """ View single profile """
        profile = model.get_profile(int(id))
        sections = model.get_sections_by_profile_id(int(id))
        return render.view(profile, sections, model)


class New:

    form = web.form.Form(
        web.form.Textbox('title', web.form.notnull, 
            size=30,
            description="Title:"),
        web.form.Textarea('content', web.form.notnull, 
            rows=30, cols=80,
            description="G-codes:"),
        web.form.Button('Save profile'),
    )

    def GET(self):
        form = self.form()
        return render.new(form)

    def POST(self):
        form = self.form()
        if not form.validates():
            return render.new(form)
        pid = model.new_profile(form.d.title, form.d.content)
        model.new_section("Init", "Handle initialization", pid)
        model.new_section("Wash", "Wash the filter", pid)
        model.new_section("Grind", "Grind the coffee", pid)
        model.new_section("Presoak", "Presoak the coffee", pid)
        model.new_section("Extract", "Extract the coffee", pid)
        model.new_section("Teardown", "Handle teardown", pid)
        raise web.seeother('/')


class Delete:
    form = web.form.Form(
        web.form.Hidden(name='id', value='1'),
        web.form.Button('Delete'),
    )

    def GET(self, id):
        form = self.form()
        return render.new(form)

    def POST(self, id):
        model.del_profile(int(id))
        raise web.seeother('/')


class Edit:

    def GET(self, id):
        profile = model.get_profile(int(id))
        form = New.form()
        form.fill(profile)
        return render.edit(profile, form, model)


    def POST(self, id):
        form = New.form()
        profile = model.get_profile(int(id))
        if not form.validates():
            return render.edit(profile, form)
        model.update_profile(int(id), form.d.title, form.d.content)
        raise web.seeother('/view/'+str(profile.id))


class Run: 

    def POST(self):
        data = web.input()
        profile = model.get_profile(int(data.id))
        web.header('Content-Type', 'application/json')

        if data.func == "start":
            if not Runner.runner.running:
                Runner.runner.line_nr = 0
                Runner.runner.gcodes = str(model.compile_profile(profile.id)).split("\n")
                Runner.runner.running = True
        elif data.func == "stop":
                Runner.runner.running = False

        return json.dumps({'running': Runner.runner.running})    
        

class Line:
   
    def GET(self):
        web.header('Content-Type', 'application/json')

        return json.dumps({
            'running': Runner.runner.running, 
            'line_nr': Runner.runner.line_nr, 
            'temp': Runner.runner.temp
        })

class Ajax:
    def GET(self, id):
        return "<pre>"+model.compile_profile(id)+"</pre>"

    def POST(self):
        data = web.input()
        func = data.func
        web.header('Content-Type', 'application/json')

        if func == "del_block":
            model.del_block(int(data.id))
            return json.dumps({})
        elif func == "new_block":
            id = model.new_block(data.type)
            return json.dumps({'id': id})
        elif func == "update_block":
            model.update_block(data.id, data.settings, data.section_id, data.index)
            return json.dumps({})

def send(self, msg):
    f = os.open("/dev/testing_1", os.O_RDWR)
    os.write(f, msg+"\n")
    while True:
        ret = self.readline(f)
        if "ok" in ret:
            break
        else:
            my_logger.critical("Got '"+ret+"'")
    os.close(f)
    return ret

def readline(self, f):
    message = ""
    while True:
        cur_char = os.read(f, 1)
        if (cur_char == '\n' or cur_char == ""):
            return message;
        message = message + cur_char

def run_gcodes(gcodes):
    my_logger.critical('run')
    for gcode in gcodes:
        gcode = gcode.strip()
        if ";" in gcode:
            gcode = gcode.split(";")[0].strip()
        if gcode != "":
            my_logger.critical("Sending '"+gcode+"'")
            ret = send(gcode+"\n")
            my_logger.critical("Got '"+ret+"'")
        line_nr += 1



app = web.application(urls, globals())

if __name__ == '__main__':
    app.run()
